package cn.itbeien.payment.service.impl;

import cn.itbeien.core.enums.PayStatus;
import cn.itbeien.core.util.SnowFlake;
import cn.itbeien.entity.TradeOrder;
import cn.itbeien.entity.TradeOrderSeq;
import cn.itbeien.payment.config.NacosConfig;
import cn.itbeien.payment.dao.TradeOrderMapper;
import cn.itbeien.payment.dao.TradeOrderSeqMapper;
import cn.itbeien.payment.message.SendMessage;
import cn.itbeien.payment.message.SimpleMsg;
import cn.itbeien.payment.service.IPaymentService;
import cn.itbeien.response.CommonResponse;
import cn.itbeien.vo.PaymentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.function.Consumer;

/**
 * @author beien
 * @date 2024-03-18 15:32
 * Copyright© 2024 beien
 */
@Service  //交由spring容器管理
@Slf4j
public class PaymentService implements IPaymentService {
   private static SnowFlake worker=new SnowFlake(1,1,1);

    @Autowired
    private TradeOrderSeqMapper tradeOrderSeqMapper;

    @Autowired
    private TradeOrderMapper tradeOrderMapper;

    @Autowired
    private NacosConfig nacosConfig;

    @Autowired
    private SendMessage sendMessage;

    @Transactional
    @Override
    public CommonResponse doService(PaymentVO paymentVO) {
        CommonResponse commonResponse = new CommonResponse();
        /**
         * 调用哪个上游机构，支付产品和支付场景
         * 把数据写入支付订单表和支付流水表
         *
         *
         */
        //paymentVO
        //记录支付订单和支付流水表
        //构造
        TradeOrder tradeOrder = new TradeOrder();
        TradeOrderSeq tradeOrderSeq = new TradeOrderSeq();
        initData(tradeOrder,tradeOrderSeq,paymentVO);
        tradeOrderMapper.insertSelective(tradeOrder);
        tradeOrderSeqMapper.insertSelective(tradeOrderSeq);


        //调用上游支付机构交易接口(微信，支付宝，云闪付支付)

        //开发一个方法，这个方式修改当前订单的订单状态
        SimpleMsg simpleMsg = new SimpleMsg("修改订单状态延迟队列");
        String orderId = tradeOrder.getOrderId();
        simpleMsg.setOrderId(tradeOrder.getOrderId());
        String key = orderId;
        String id = orderId;
        String delayLevel = "2";
        //发送延迟消息
        sendMessage.sendDelayMsg(key,id,delayLevel,simpleMsg);

        return commonResponse;
    }


    private void initData(TradeOrder tradeOrder, TradeOrderSeq tradeOrderSeq,PaymentVO paymentVO){
        //初始化订单数据对象
        long id = worker.nextId();
        //orderId = 机构号+id
        String orderId = "1001"+worker.nextId();
        tradeOrder.setOrderId(orderId);
        BigDecimal amount =  BigDecimal.valueOf(Double.valueOf(paymentVO.getAmount()));
        tradeOrder.setOrderAmount(amount);//订单金额
        tradeOrder.setOrderTime(new Date());//获取当前数据库时间，获取应用服务器时间
        tradeOrder.setNotifyUrl(nacosConfig.getNotifyUrl());//从nacos中获取,上游支付机构根据后台的回调地址调用我们的Controller方法
        tradeOrder.setRemark(paymentVO.getOrderRemark());//订单备注
        tradeOrder.setCreateTime(new Date());
        tradeOrder.setPayStatus(PayStatus.pay_paying.getCode());
        tradeOrder.setTermType(paymentVO.getTermType());//终端类型
        //todo 查询商户支付渠道映射表，根据商户编号获取支付渠道编号，渠道商户号，终端编号
        tradeOrder.setChannelCode("");//支付渠道编号,商户和上游机构的中间表
        tradeOrder.setPaywayCode(paymentVO.getProductCode());//产品类型
        tradeOrder.setSceneCode(paymentVO.getPayType());//支付场景

        //设置支付流水对象
        tradeOrderSeq.setOrderId(orderId);
        tradeOrderSeq.setTradeSeq(String.valueOf(worker.nextId()));
        tradeOrderSeq.setFeeValue(new BigDecimal(100.00));//回佣值
        ////支付机构返回的流水号 在支付回调方法中设置
        //tradeOrderSeq.setBankTradeSeq();
        //支付渠道编号，渠道商户号  从商户和上游机构中间表获取




    }

    @Override
    public CommonResponse callBack(String data) {
        //http://192.168.1.2/pay/

        return null;
    }

    /**
     * 通过rocketmq延迟队列实现订单状态的修改
     * @param orderId 订单号
     * @param status  支付状态
     * @return
     */
    @Transactional
    @Override
    public String updateOrderStatus(String orderId, String status) {
        String result ="fail";
        try{
            //判断当前支付状态是否为待支付,如果为待支付状态则把订单状态修改为关闭
            int orderNumber =  this.tradeOrderMapper.updateStatusByOrderId(orderId,status);
            int seqNumber = this.tradeOrderSeqMapper.updateStatusByOrderId(orderId,status);
            if(orderNumber>0 && seqNumber>0){
                result = "success";
            }
        }catch (Exception e){
            log.error("通过延迟队列-修改订单状态失败:{}",e);
        }
        return result;
    }


    @Bean
    public Consumer<Message<SimpleMsg>> consumer() {
        return msg -> {
            String success  = updateOrderStatus(msg.getPayload().getOrderId(),PayStatus.pay_canal.getCode());
            log.debug("延迟队列执行的结果:{}",success);
        };

    }


}
